home *** CD-ROM | disk | FTP | other *** search
- 1000 LN=1000: LD=11: REM LN=Max data points; LD=highest degree+1
- 1010 DEF FNMI(X,Y)=(X<Y)*(-X) + (Y<=X)*(-Y)
- 1020 N=0: M=0: S2=0: R2=0: MF=0
- 1030 S1=0: S2=0: S3=0: S4=0: P1=0: P2=0: P3=0: I=0: J=0: J1=0: K=0: VR=0: MM=0: WT=0: P=0
- 1040 DIM X(LN),Y(LN),W(LN),C(LD)
- 1050 DIM D1(LD),D2(LD),D3(LD),D4(LD),D5(LD),D6(LD)
- 1060 GOTO 1450
- 1070 IF MF>0 AND M>MM THEN J1=MM+1: MM=M: GOTO 1130
- 1080 J1=1: MM=M: S1=0: S2=0: S3=0: S4=0
- 1090 FOR I=1 TO N: WT=W(I)
- 1100 S1=S1+WT*X(I): S2=S2+WT: S3=S3+WT*Y(I): S4=S4+WT*Y(I)*Y(I)
- 1110 NEXT I
- 1120 D4(1)=S1/S2: D5(1)=0: D6(1)=S3/S2: D1(1)=0: D2(1)=1: VR=S4-S3*D6(1)
- 1130 FOR J=J1 TO MM: S1=0: S2=0: S3=0: S4=0
- 1140 FOR I=1 TO N: P1=0: P2=1
- 1150 FOR K=1 TO J: P=P2: P2=(X(I)-D4(K))*P2-D5(K)*P1: P1=P: NEXT K
- 1160 WT=W(I): P=WT*P2*P2
- 1170 S1=S1+P*X(I): S2=S2+P: S3=S3+WT*P1*P1: S4=S4+WT*Y(I)*P2: NEXT I
- 1180 D4(J+1)=S1/S2: D5(J+1)=S2/S3: D6(J+1)=S4/S2: D3(1)=-D4(J)*D2(1)-D5(J)*D1(1)
- 1190 IF J<4 THEN 1210
- 1200 FOR K=2 TO J-2: D3(K)=D2(K-1)-D4(J)*D2(K)-D5(J)*D1(K): NEXT K
- 1210 IF J>2 THEN D3(J-1)=D2(J-2)-D4(J)*D2(J-1)-D5(J)
- 1220 IF J>1 THEN D3(J)=D2(J-1)-D4(J)
- 1230 FOR K=1 TO J: D1(K)=D2(K): D2(K)=D3(K): D6(K)=D6(K)+D3(K)*D6(J+1): NEXT K
- 1240 NEXT J
- 1250 FOR J=1 TO M+1: C(J)=D6(M+2-J): NEXT J
- 1260 P2=0: FOR I=1 TO N: P=C(1)
- 1270 FOR J=1 TO M: P=P*X(I)+C(J+1): NEXT J
- 1280 P=P-Y(I): P2=P2+W(I)*P*P: NEXT I
- 1290 S2=0: IF N>M+1 THEN S2=P2/(N-M-1)
- 1300 R2=1: IF VR<>0 THEN R2=1-P2/VR: IF R2<0 THEN R2=0
- 1310 RETURN
- 1320 REM GOSUB 30 calls the subroutine
- 1330 REM Input:
- 1340 REM N=# of data points
- 1350 REM X()=X-coordinates of the data points
- 1360 REM Y()=Y-coordinates of the data points
- 1370 REM W()=Weighting factors of the data points
- 1380 REM M=Degree of polynomial
- 1390 REM MF=0 if new data, MF=1 if old data but higher degree
- 1400 REM
- 1410 REM Output:
- 1420 REM C=Array of M+1 coefficients
- 1430 REM S2=Residual variance
- 1440 REM R2=coefficient of determination
- 1450 CLS
- 1460 PRINT "Polyfit. Copyright (C) 1986 by William G. Hood"
- 1470 PRINT
- 1480 PRINT "This program finds the coefficients of the nth degree polynomial"
- 1490 PRINT: PRINT "y = c(1)*x^n + c(2)*x^(n-1) + ... + c(n)*x + c(n+1)
- 1500 PRINT: PRINT "that fits a set of data points in a least-squares sense."
- 1510 PRINT "Each data point must consist of an X value, a Y value, and an
- 1520 PRINT "optional weight, separated by commas and terminated by a return.
- 1530 PRINT "Data are read from a disk file until the eof is reached, or a
- 1540 PRINT "specified number of data points are read in from the keyboard."
- 1550 PRINT
- 1560 LINE INPUT "Name the data file (null line=keyboard): "; FI$
- 1570 PRINT "Is the data weighted (Y/N, null line=No)? ";
- 1580 W$="": INPUT W$
- 1590 IF W$<>"Y" AND W$<>"y" THEN W$="N"
- 1600 IF FI$<>NU$ THEN 2000
- 1610 PRINT "Keyboard data entry"
- 1620 PRINT "How many data points ( 2 <= n <=";LN;")";: INPUT N
- 1630 IF N<2 OR N>LN THEN 1620
- 1640 FOR K=1 TO N
- 1650 IF W$<>"N" THEN INPUT "x,y,w";X(K),Y(K),W(K): W(K)=ABS(W(K))
- 1660 IF W$="N" THEN INPUT "x,y"; X(K),Y(K): W(K)=1
- 1670 NEXT K
- 1680 PM=FNMI(LD-1,N-1)
- 1690 PRINT "Degree of polynomial ( 1<= m <= "; PM;")";: INPUT M: M=INT(M)
- 1700 IF M<1 OR M>PM THEN 1690
- 1710 GOSUB 1070
- 1720 PRINT: PRINT "Coefficients (constant term last): ": K=0
- 1730 FOR J=1 TO M+1: PRINT TAB(K) C(J);: K=K+20: IF K>20 THEN K=0: PRINT
- 1740 NEXT J
- 1750 PRINT: PRINT "Residual variance: ";S2
- 1760 R2=INT(1000000!*R2+.5)/1000000!
- 1770 PRINT: PRINT"Coefficient of determination: ";R2
- 1780 PRINT "Try another degree (Y/N, null line=No)";: A$="": INPUT A$
- 1790 IF A$="Y" OR A$="y" THEN 1680
- 1800 PRINT "Print a table of the data (Y/N, null line=No)";: A$="": INPUT A$
- 1810 IF A$<>"Y" AND A$<>"y" THEN 1870
- 1820 PRINT: PRINT"Degree of p(x): ";M
- 1830 PRINT: PRINT " X"; TAB(11) "Y"; TAB(25) "p(x)": PRINT
- 1840 FOR I=1 TO N: P=C(1)
- 1850 FOR K=1 TO M: P=P*X(I)+C(K+1): NEXT K
- 1860 PRINT X(I);TAB(10);Y(I);TAB(24);P: NEXT I
- 1870 IF F$<>NU$ THEN END
- 1880 PRINT: PRINT "Save the data (Y/N, null line=No)? ";: A$="": INPUT A$
- 1890 IF A$<>"Y" AND A$<>"y" THEN END
- 1900 PRINT: LINE INPUT "Name of output file ";FO$
- 1910 IF FO$=NU$ THEN END
- 1920 PRINT "Writing to ";FO$
- 1930 OPEN FO$ FOR OUTPUT AS 1
- 1940 FOR I=1 TO N
- 1950 IF W$<>"N" THEN PRINT#1, X(I);","; Y(I);","; W(I)
- 1960 IF W$="N" THEN PRINT#1, X(I);","; Y(I)
- 1970 NEXT I
- 1980 CLOSE 1
- 1990 END
- 2000 PRINT "Reading from ";FI$
- 2010 OPEN FI$ FOR INPUT AS 1
- 2020 N=0
- 2030 PRINT " X" TAB(15) "Y"; TAB(28) "W"; : PRINT
- 2040 IF EOF(1) OR N=LN THEN 2100
- 2050 N=N+1
- 2060 IF W$<>"N" THEN INPUT#1, X(N), Y(N), W(N): W(N)=ABS(W(N))
- 2070 IF W$="N" THEN INPUT#1, X(N), Y(N): W(N)=1
- 2080 PRINT X(N) TAB(14) Y(N) TAB(28) W(N)
- 2090 GOTO 2040
- 2100 CLOSE 1
- 2110 PRINT: PRINT"File contained "; N;" data points."
- 2120 IF N<2 THEN PRINT "Too few data points.": END
- 2130 GOTO 1680
-